package com.money.tracker.auth.service.transfer;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.money.tracker.common.constant.MoneyTrackerConstant;
import com.money.tracker.common.entity.LoginUser;
import com.money.tracker.common.enums.IResponseEnum;
import com.money.tracker.common.utils.LoginUtil;
import com.money.tracker.common.utils.StreamUtil;
import com.money.tracker.generator.constant.GenConstants;
import com.money.tracker.generator.entity.GenTable;
import com.money.tracker.generator.entity.GenTableColumn;
import com.money.tracker.generator.utils.GenUtil;
import com.money.tracker.auth.entity.SysDept;
import com.money.tracker.auth.entity.SysMenu;
import com.money.tracker.auth.entity.SysUser;
import com.money.tracker.auth.entity.rsp.MetaRsp;
import com.money.tracker.auth.entity.rsp.RouterRsp;
import com.money.tracker.auth.entity.rsp.UserInfoRsp;
import com.money.tracker.auth.enums.CacheEnum;
import com.money.tracker.auth.enums.FrameEnum;
import com.money.tracker.auth.enums.MenuTypeEnum;
import com.money.tracker.auth.enums.VisibleEnum;
import com.money.tracker.system.entity.SysConfig;
import com.money.tracker.system.entity.SysLog;
import com.money.tracker.system.service.SysConfigService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 数据拼装service
 * <p>
 *
 * @author zhangshuai
 * &#064;@date 2024/09/25
 */
@Service
@RequiredArgsConstructor
public class SysTransferService {

    private final SysConfigService sysConfigService;

    /**
     * 构造LoginUser
     *
     * @param sysUser
     * @param menuPermission
     * @param rolePermission
     * @param sysDept
     * @return {@link LoginUser }
     */

    public LoginUser buildLoginUser(SysUser sysUser, Set<String> menuPermission, Set<String> rolePermission, SysDept sysDept) {
        return LoginUser.builder()
                .userId(sysUser.getId())
                .deptId(sysUser.getDeptId())
                .username(sysUser.getUserName())
                .userType(sysUser.getUserType())
                .menuPermission(menuPermission)
                .rolePermission(rolePermission)
                .deptName(sysDept.getDeptName())
                .build();
    }

    public SysLog buildSysLog(String username, IResponseEnum iResponseEnum) {
        return SysLog.builder()
                .userName(username)
                .msg(iResponseEnum.getMsg())
                .status(iResponseEnum.getCode())
                .build();
    }

    public UserInfoRsp buildUserInfo(SysUser sysUser, LoginUser loginUser) {
        UserInfoRsp userInfoRsp = UserInfoRsp.builder().build();
        BeanUtils.copyProperties(sysUser, userInfoRsp);
        userInfoRsp.setRoles(loginUser.getRolePermission());
        return userInfoRsp;
    }

    public List<RouterRsp> buildRouterRsp(List<SysMenu> sysMenus) {
        return StreamUtil.toList(sysMenus, sysMenu -> {
            RouterRsp.RouterRspBuilder routerRspBuilder = RouterRsp.builder()
                    .hidden(VisibleEnum.isShow(sysMenu.getVisible()))
                    .name(MenuTypeEnum.getRouteName(sysMenu))
                    .path(MenuTypeEnum.getRouterPath(sysMenu))
                    .component(FrameEnum.getComponent(sysMenu))
                    .query(sysMenu.getQueryParam())
                    .meta(buildMeta(sysMenu));
            List<SysMenu> cMenus = sysMenu.getChildren();
            // 目录
            if (CollectionUtil.isNotEmpty(cMenus) && MenuTypeEnum.isCatalog(sysMenu.getMenuType())) {
                routerRspBuilder.alwaysShow(true);
                routerRspBuilder.redirect("noRedirect");
                routerRspBuilder.children(buildRouterRsp(cMenus));
                return routerRspBuilder.build();
            }
            // 菜单内部跳转
            if (MenuTypeEnum.isMenuFrame(sysMenu)) {
                routerRspBuilder.meta(null);
                List<RouterRsp> childrenList = new ArrayList<>();
                RouterRsp children = new RouterRsp();
                children.setPath(sysMenu.getPath());
                children.setComponent(sysMenu.getComponent());
                children.setName(StringUtils.capitalize(sysMenu.getPath()));
                children.setMeta(buildMeta(sysMenu));
                children.setQuery(sysMenu.getQueryParam());
                childrenList.add(children);
                routerRspBuilder.children(childrenList);
                return routerRspBuilder.build();
            }
            // 内链组件
            if (sysMenu.getParentId().intValue() == 0 && FrameEnum.noFrame(sysMenu.getIsFrame()) && Validator.isUrl(sysMenu.getPath())) {
                routerRspBuilder.path("/");
                List<RouterRsp> childrenList = new ArrayList<>();
                RouterRsp children = new RouterRsp();
                children.setPath(sysMenu.getPath());
                children.setComponent(MoneyTrackerConstant.INNER_LINK);
                children.setName(StringUtils.capitalize(sysMenu.getPath()));
                children.setMeta(buildMeta(sysMenu));
                childrenList.add(children);
                routerRspBuilder.children(childrenList);
                return routerRspBuilder.build();

            }
            return routerRspBuilder.build();
        });
    }


    private MetaRsp buildMeta(SysMenu sysMenu) {
        return MetaRsp.builder()
                .icon(sysMenu.getIcon())
                .title(sysMenu.getMenuName())
                .noCache(CacheEnum.isCache(sysMenu.getIsCache()))
                .link(Validator.isUrl(sysMenu.getPath()) ? sysMenu.getPath() : null)
                .build();
    }


    public GenTable buildGenTable(TableInfo tableInfo) {
        // 拿默认配置信息--->包名
        SysConfig pageNameConfig = sysConfigService.getSysConfig(MoneyTrackerConstant.PACKAGE_NAME);
        String pageName = MoneyTrackerConstant.PACKAGE_NAME;
        if (Objects.nonNull(pageNameConfig)) {
            pageName = pageNameConfig.getConfigValue();
        }
        // 拿默认配置信息--->作者
        SysConfig authorConfig = sysConfigService.getSysConfig(MoneyTrackerConstant.AUTHOR);
        String author = MoneyTrackerConstant.AUTHOR;
        if (Objects.nonNull(authorConfig)) {
            author = authorConfig.getConfigValue();
        }
        // 要去除的表前缀
        SysConfig tablePrefixesConfig = sysConfigService.getSysConfig(MoneyTrackerConstant.TABLE_PREFIX);
        String tablePrefixes = MoneyTrackerConstant.TABLE_PREFIX;
        if (Objects.nonNull(tablePrefixesConfig)) {
            tablePrefixes = tablePrefixesConfig.getConfigValue();
        }

        GenTable genTable = GenTable.builder()
                .className(GenUtil.convertClassName(tableInfo.getName(), tablePrefixes))
                .packageName(pageName)
                .moduleName(GenUtil.getModuleName(pageName))
                .businessName(GenUtil.getBusinessName(tableInfo.getName()))
                .functionName(GenUtil.replaceText(tableInfo.getComment()))
                .functionAuthor(author)
                .tableComment(tableInfo.getComment())
                .tableName(tableInfo.getName())
                .build();
        genTable.setCreateBy(LoginUtil.getUserId());
        return genTable;
    }

    public GenTableColumn buildGenTableColumn(GenTable genTable, TableField columnInfo) {
        GenTableColumn.GenTableColumnBuilder genTableColumnBuilder = GenTableColumn.builder()
                .tableId(genTable.getId())
                .isPk(columnInfo.isKeyFlag() ? 1 : 0)
                .columnName(columnInfo.getColumnName())
                .columnType(columnInfo.getType())
                .columnComment(columnInfo.getComment())
                .javaType(columnInfo.getPropertyType())
                .javaField(columnInfo.getPropertyName())
                .fieldGetMethod(buildFieldGetMethod(columnInfo.getPropertyName()))
                .queryType(GenConstants.QUERY_EQ);
        // 生成的Java类型是布尔类型，改成Integer类型
        if (StringUtils.equalsIgnoreCase(columnInfo.getPropertyType(), GenConstants.TYPE_BOOLEAN)) {
            genTableColumnBuilder.javaType(GenConstants.TYPE_INTEGER);
        }
        String columnName = columnInfo.getColumnName();
        // 字符串长度超过500设置为文本域
        TableField.MetaInfo metaInfo = columnInfo.getMetaInfo();

        // req对象 默认勾选
        if (!GenUtil.arraysContains(GenConstants.COLUMNNAME_NOT_ADD, columnName) && !columnInfo.isKeyFlag()) {
            genTableColumnBuilder.isInsert(GenConstants.REQUIRE);
        }
        // req对象 默认编辑勾选
        if (!GenUtil.arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) {
            genTableColumnBuilder.isEdit(GenConstants.REQUIRE);
        }
        // req对象 默认是否必填勾选
        if (!GenUtil.arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) {
            genTableColumnBuilder.isRequired(GenConstants.REQUIRE);
        }
        // rsp对象 默认返回勾选
        if (!GenUtil.arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName)) {
            genTableColumnBuilder.isList(GenConstants.REQUIRE);
        }
        // req对象 默认查询勾选
        if (!GenUtil.arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !columnInfo.isKeyFlag()) {
            genTableColumnBuilder.isQuery(GenConstants.REQUIRE);
        }
        // 查询字段类型
        if (StringUtils.endsWithIgnoreCase(columnName, GenConstants.NAME)) {
            genTableColumnBuilder.queryType(GenConstants.QUERY_LIKE);
        }
        if (GenUtil.arraysContains(GenConstants.COLUMNTYPE_TEXT, columnName)) {
            String htmlType = metaInfo.getLength() >= 500 || GenUtil.arraysContains(GenConstants.COLUMNTYPE_TEXT, columnName) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
            genTableColumnBuilder.htmlType(htmlType);
        } else if (GenUtil.arraysContains(GenConstants.COLUMNTYPE_TIME, columnName)) {
            // 日期类型设置日期控件
            genTableColumnBuilder.htmlType(GenConstants.HTML_DATETIME);
        } else if (GenUtil.arraysContains(GenConstants.COLUMNTYPE_NUMBER, columnName)) {
            // 数字类型--->设置文本框
            genTableColumnBuilder.htmlType(GenConstants.HTML_INPUT);
        } else if (StringUtils.endsWithIgnoreCase(columnName, GenConstants.STATUS)) {
            // 状态字段设置单选框
            genTableColumnBuilder.htmlType(GenConstants.HTML_RADIO);
        } else if (StringUtils.endsWithIgnoreCase(columnName, GenConstants.TYPE)
                || StringUtils.endsWithIgnoreCase(columnName, GenConstants.SEX)) {
            // 类型&性别字段设置下拉框
            genTableColumnBuilder.htmlType(GenConstants.HTML_SELECT);
        } else if (StringUtils.endsWithIgnoreCase(columnName, GenConstants.IMAGE)) {
            // 图片字段设置图片上传控件
            genTableColumnBuilder.htmlType(GenConstants.HTML_IMAGE_UPLOAD);
        } else if (StringUtils.endsWithIgnoreCase(columnName, GenConstants.FILE)) {
            // 文件字段设置文件上传控件
            genTableColumnBuilder.htmlType(GenConstants.HTML_FILE_UPLOAD);
        } else if (StringUtils.endsWithIgnoreCase(columnName, GenConstants.CONTENT)) {
            // 内容字段设置富文本控件
            genTableColumnBuilder.htmlType(GenConstants.HTML_EDITOR);
        }
        return genTableColumnBuilder.build();
    }

    private String buildFieldGetMethod(String propertyName) {
        return MoneyTrackerConstant.GETTER_PREFIX + StringUtils.capitalize(propertyName);
    }
}
